package com.zoweunion.mechanic.util.calculate;

/**
 * 计算方差
 */
public class CalculateVarianceUtil {

    /**
     * 平均值
     * @param data
     * @return
     */
    public static double average (double[] data) {
        double sum = 0;
        int len = data.length;
        for (double datum : data) {
            sum += datum;
        }
        return sum / len;
    }

    /**
     * 标准方差
     * @param data
     * @return
     */
    public static double variance(double[] data) {
        double mean = average(data);
        double sum = 0;
        int len = data.length;
        double delta = 0;
        for (int i = 0; i < len; i++) {
            delta = data[i] - mean;
            sum += (delta * delta);
        }
        return sum / len;
    }

    /**
     * 标准差 / 标准误差
     * @param data
     * @return
     */
    public static double standardDeviation(double[] data) {
        return Math.sqrt(variance(data));
    }

    /**
     * 协方差
     * @param X
     * @param Y
     * @return
     */
    public static double covariance(double[] X, double[] Y) {
        double mx = average(X);
        double my = average(Y);
        // 理论上应该通过插值保证长度一致
        int len = X.length == Y.length ? X.length : Math.min(X.length, Y.length);
        double sum = 0;
        for (int i = 0; i < len; i++) {
            sum += ((X[i] - mx) * (Y[i] - my));
        }
        return sum / len;
    }

    public static void main(String[] args) {
        int len = 20;
        double[] X = new double[len];
        double[] Y = new double[len];
        for (int i = 0; i < len; i++) {
            X[i] = Math.random() * 100;
            Y[i] = Math.random() * 100;
        }
        System.out.println("X Average: " + CalculateVarianceUtil.average(X));
        System.out.println("Y Average: " + CalculateVarianceUtil.average(Y));
        System.out.println();

        System.out.println("X Variance: " + CalculateVarianceUtil.variance(X));
        System.out.println("Y Variance: " + CalculateVarianceUtil.variance(Y));
        System.out.println();

        System.out.println("X Standard Deviation: " + CalculateVarianceUtil.standardDeviation(X));
        System.out.println("Y Standard Deviation: " + CalculateVarianceUtil.standardDeviation(Y));
        System.out.println();

        System.out.println("XY Covariance: " + CalculateVarianceUtil.covariance(X, Y));
        System.out.println();
    }
}
